bash
альтернатива для ответа Stephane:
diff -u <(cd dir1 && du -a | sort -k2) <(cd dir2 && du -a | sort -k2)
И ответ этого и Stephane предполагает, что нет никаких новых строк в Ваших именах файлов.
Вот несколько опций:
basename
как предложенный Stephane
$ basename /1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat
20140111_PR1_018_SALESDOC_ITEM_001.dat
basename
часть coreutils
и просто разделяет путь от имен файлов.
awk
$ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" |
awk -F'/' '{print $NF}'
-F
опция к awk
определяет разделителя полей. Так, мы устанавливаем это на /
и затем распечатайте последнее поле ($NF
).
cut
$ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" |
cut -d '/' -f 6
-d
разделитель полей и -f 6
говорит cut
только распечатать 5-е поле.
Это - очень ограниченный подход, хотя, так как он требует, чтобы Вы знали количество полей заранее. Лучший путь состоял бы в том, чтобы использовать rev
(который инвертирует, это вводится) сделать последнее поле сначала, затем cut
получить 1-е поле и затем rev
для получения его назад путь, он был:
$ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" |
rev | cut -d/ -f1 | rev
Perl
$ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" |
perl -pe 's/.+?([^\/]+)$/$1/;'
-p
флаг говорит perl
для печати каждой входной строки после выполнения безотносительно, сценарий дан как -e
. В этом случае говорим мы просто perl
заменять все до самого длинного фрагмента не -/
персонажи. Так как это - Perl, существует много способов сделать это:
$ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" |
perl -F/ -ane 'print $F[$#F]'
-a
флаг говоритperl
вести себя как awk
, это автоматически разделит каждую входную строку на @F
массив. Так, мы устанавливаем разделитель полей на /
с -F
и затем распечатайте последний элемент массива ($F[$#F]
). -n
причины perl
для цикличного выполнения по, он вводится линию за линией.
grep
$ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" |
grep -Po '[^/]+$'
-P
активирует PCREs и -o
означает, "только печатают совпавшую строку". Так, говорим мы grep
искать самую длинную строку не -/
в конец входной строки ($
).
оболочка
$ foo="/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat";
$ printf "${foo##*/}\n"
Это использует в своих интересах способности к обработке строк оболочки. А именно, конструкция ${var##pattern}
удалит самое долгое соответствие pattern
от передней стороны $var
. Так,##*/
средства удаляют все до последнего /
.
sed
$ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" |
sed 's/.*\///'
sed
заменит всем до последнего /
.
Вы должны echo
строка в cut
:
echo "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" | cut -d/ -f6
(обратите внимание, что поле # равняется 6),
Но использование комментария Stephane basename
лучший путь состоит в том, чтобы сделать это.
echo
но printf
вместо этого. Также отметьте это cut
сокращает поля каждой строки входа, таким образом, это не может использоваться для произвольных имен файлов, поскольку имена файлов могут быть сделаны из нескольких строк.
– Stéphane Chazelas
14.01.2014, 12:13
${foo##*/}
определяется в POSIX, regex синтаксис не. – Patrick 14.01.2014, 15:20##
выбор. – terdon♦ 14.01.2014, 15:24tail
на grep решении путем выполненияgrep -Po '[^/]+$'
– Patrick 14.01.2014, 15:26