Каков наилучший способ сделать это преобразование строки в оболочке? - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь написать сценарий оболочки, который должен будет преобразовать ввод следующей формы:

foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt

В

baz-qux
quz
foo

т.е. разделить на '/', отбросить первые 2 сегмента, отбросить '.txt' и заменить оставшиеся слэши дефисами.

Замена кажется достаточно простой, используя tr:

paths=$(cat <<- EOF
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
EOF
)

echo $paths | tr '/' '-' | tr '.txt' ' '

Я пробовал различные формы

cut -d '/' -f x

Чтобы получить необходимые сегменты, но у меня короткая позиция.

Я - рубиновый парень, так искушенный дотянуться до моего молотка и просто использовать рубин:

lines.each { |s| s.split('/')[2..-1].join('-').split('.')[0] }

Но развертывание ruby ​​для этой операции может показаться излишним. И я все равно хотел бы улучшить свои навыки работы с оболочкой, поэтому мне было интересно, есть ли более изящный способ, который кто-нибудь посоветует сделать в оболочке?

Спасибо за любую помощь

Ответы [ 6 ]

0 голосов
/ 08 января 2019
awk '{gsub(/^.{8}|.txt$/,"")sub(/\//,"-")}1' file

baz-qux
quz
foo
0 голосов
/ 08 января 2019

при условии . только в именах файлов

$ awk -F[/.] '{n=NF; p=$(n-1)} n>4{p=$(n-2)"-"p} {print p}' file

baz-qux
quz
foo
0 голосов
/ 07 января 2019

Попробуйте Perl

$ cat mark_smith.txt
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt

$ perl -F"/" -lane ' @a=@F[2..$#F]; @b=map{s/.txt//g;$_} @a; print join("-",@b) ' mark_smith.txt
baz-qux
quz
foo

$
0 голосов
/ 07 января 2019

Вы можете сделать все за одну sed команду

sed -E 's|([^/]*/){,2}||; s|/|-|g; s|\.txt$||' file

Замените \.txt$ на \.[^.]$, чтобы удалить все расширения вместо .txt.

0 голосов
/ 07 января 2019

Вы можете попробовать что-то вроде этого: cut -d/ -f3- | cut -d. -f1 | tr / -

Пояснение:

  • cut -d/ -f3- - разделить на '/' и оставить третье поле и все после него (baz/qux.txt)
  • cut -d. -f1 - разделить на '.', Сохранить первое значение (удаляет расширение файла) (baz/qux)
  • tr / - - Преобразуйте все оставшиеся символы '/' в '-'. (baz-qux)
0 голосов
/ 07 января 2019

Это можно сделать с помощью bash расширения параметров :

for name in foo/bar/baz/qux.txt bar/baz/quz.txt baz/quz/foo.txt; do
    new=${name#*/}   # drop the shortest prefix match for */, thus everything up to first /
    new=${new#*/}    # repeat, dropping the second segment
    new=${new%.txt}  # drop shortest suffix match for .txt
    new=${new//\//-} # convert any remaining slashes
    echo "$new"
done

Дает:

baz-qux
quz
foo

Это все встроенные конструкции оболочки bash, поэтому внешние процессы, такие как cut, sed или tr не требуются.

...