Разделить строку по некоторому разделителю в bash?

Стандартный find не может выводить информацию о найденных файлах отдельно, кроме их полных путей.Однако в некоторых найденных реализациях есть расширения для этого.

Например, с GNU find (как в большинстве общих / традиционных дистрибутивов GNU / Linux):

find ~ -type l -printf '%p -> %l\n'

Напечатает символические ссылки в запрошенном вами формате для рекурсивно найденных символических ссылок ( выполняя физический обход , не следуя символическим ссылкам на каталоги) в вашем домашнем каталоге. Некоторые реализации find также имеют предикат -ls для вывода в формате, аналогичном ls -li , из которого вы можете извлечь информацию.

Если вы хотите выполнить логический обход (следуйте символическим ссылкам на каталоги) и распечатайте эту информацию, вы не сможете сделать это одним вызовом find (даже с GNU find ), но вместо этого вы можете использовать подстановку zsh для обхода каталогов и использовать GNU find только для печати информации:

find ~/***/*(D@) -printf '%p -> %l\n'

Или с любой оболочкой и GNU find (но несколько вызовов):

find -L ~ -xtype l -exec sh -c '
  exec find "$@" -printf "%p -> %l\n"' sh {} +

Чтобы найти символические ссылки, которые в конечном итоге указывают на некоторый существующий файл в ~ / bin / config (предполагается, что ни один из компонентов ~ / bin / config не является самим символическими ссылками), все еще с zsh :

find ~/**/*(D@e{'[[ $REPLY:A = ~/bin/config/* ]]'}) -printf '%p -> %l\n'
4
14.07.2017, 23:35
5 ответов

Чистый раствор Баша с использованием IFSи read. Обратите внимание, что строки не должны содержать$'\2'(или что-то еще, что вы используете для IFS, к сожалению, $'\0'не работает, но, например. $'\666'делает):

#!/bin/bash

split_by () {
    string=$1
    separator=$2

    tmp=${string//"$separator"/$'\2'}
    IFS=$'\2' read -a arr <<< "$tmp"
    for substr in "${arr[@]}" ; do
        echo "<$substr>"
    done
    echo
}


split_by '1--123--23' '--'
split_by '1?*123' '?*'

Или используйте Perl:

perl -E 'say for split quotemeta shift, shift' -- "$separator" "$string"
14
27.01.2020, 20:46

Просто с помощью awk:

str="1--123--23"
awk -F'--' '{ for(i=1;i<=NF;i++) print $i }' <<< $str

Выход:

1
123
23

Еще одно короткоерешение Python:

splitter.pyсценарий:

import sys
print('\n'.join(sys.argv[2].split(sys.argv[1])))

порядок аргументов:

  • sys.argv[0]-имя скрипта (т.е.splitter.py)

  • sys.argv[1]-разделитель подстрок

  • sys.argv[2]-входная строка

Использование:

python splitter.py "?*" "1?*123"
1
123

python splitter.py "--" "1--23--123"
1
23
123
4
27.01.2020, 20:46

Аналогично предыдущему, но скажем, что вы просто хотите получить URI, например:

URL="http://something.com/backup/v/photos/path/to/"
URI="./$(echo $URL | awk -F'.com/' '{print $2}')"
echo $URI
0
27.01.2020, 20:46

Чистая оболочка POSIX:

string="1--123--23"
del="--"

while test "${string#*$del}" != "$string" ; do
  echo "${string%%$del*}"
  string="${string#*$del}"
done
echo "$string"

Обратите внимание, что *или ?необходимо экранировать в разделителе:del='\*'

5
27.01.2020, 20:46
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


substring () {
    string=${1}
    separator=${2}
    position=${3}

    substring=${string//"${separator}"/$'\2'}
    IFS=$'\2' read -a substring <<< "${substring}"
    echo ${substring[${position}]}
}


substring ${@}
0
27.01.2020, 20:46

Теги

Похожие вопросы