Сократите строку - Выгода: существует файл с тем же именем как строка в том же пути

bash альтернатива для ответа Stephane:

diff -u <(cd dir1 && du -a | sort -k2) <(cd dir2 && du -a | sort -k2)

И ответ этого и Stephane предполагает, что нет никаких новых строк в Ваших именах файлов.

4
14.01.2014, 11:47
2 ответа

Вот несколько опций:

  1. basename как предложенный Stephane

    $ basename /1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat
    20140111_PR1_018_SALESDOC_ITEM_001.dat
    

    basename часть coreutilsи просто разделяет путь от имен файлов.

  2. awk

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" | 
       awk -F'/' '{print $NF}'
    

    -F опция к awk определяет разделителя полей. Так, мы устанавливаем это на /и затем распечатайте последнее поле ($NF).

  3. 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
    
  4. 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 для цикличного выполнения по, он вводится линию за линией.

  5. grep

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" | 
      grep -Po '[^/]+$'
    

    -P активирует PCREs и -o означает, "только печатают совпавшую строку". Так, говорим мы grep искать самую длинную строку не -/ в конец входной строки ($).

  6. оболочка

    $ foo="/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat";     
    $ printf "${foo##*/}\n" 
    

    Это использует в своих интересах способности к обработке строк оболочки. А именно, конструкция ${var##pattern} удалит самое долгое соответствие pattern от передней стороны $var. Так,##*/средства удаляют все до последнего /.

  7. sed

    $ printf "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat\n" | 
       sed 's/.*\///'
    

    sed заменит всем до последнего /.

4
27.01.2020, 20:52
  • 1
    Для ответа оболочки, делая ${foo##*/} определяется в POSIX, regex синтаксис не. –  Patrick 14.01.2014, 15:20
  • 2
    @Patrick благодарит, так regex (или это - шарик?) вещь удара? –  terdon♦ 14.01.2014, 15:22
  • 3
    да. много оболочек имеют его, таким образом, это все еще довольно портативно, просто не стандарт. достаточно ярмарка –  Patrick 14.01.2014, 15:23
  • 4
    @Patrick, я добавил ## выбор. –  terdon♦ 14.01.2014, 15:24
  • 5
    Можно также отбросить tail на grep решении путем выполнения grep -Po '[^/]+$' –  Patrick 14.01.2014, 15:26

Вы должны echo строка в cut:

echo "/1a/ftproot/archive/ABC/20140111_PR1_018_SALESDOC_ITEM_001.dat" | cut -d/ -f6

(обратите внимание, что поле # равняется 6),

Но использование комментария Stephane basename лучший путь состоит в том, чтобы сделать это.

2
27.01.2020, 20:52
  • 1
    Обратите внимание, что для произвольных данных, Вы не должны использовать echo но printf вместо этого. Также отметьте это cut сокращает поля каждой строки входа, таким образом, это не может использоваться для произвольных имен файлов, поскольку имена файлов могут быть сделаны из нескольких строк. –  Stéphane Chazelas 14.01.2014, 12:13
  • 2
    @StephaneChazelas. Я должен удалить свой ответ или обновление? Я думаю, что все еще хорошо, то, что это объясняет, почему вещи пошли не так, как надо способ, которым сделал Rakesh. –  Timo 14.01.2014, 12:26
  • 3
    Да.. На самом деле я использовал это в сценарии оболочки.. и это не работало... Я должен был использовать awk, и $ –  Rakesh K 14.01.2014, 12:31
  • 4
    display= печати ($ эха {файл} |awk-F" /" '{печатают 6$}').. здесь $file содержит строку, которую я хочу отредактировать. –  Rakesh K 14.01.2014, 12:32
  • 5
    Как Stephane записал, у Вас будут проблемы, если имя файла будет иметь новые строки. Важный то, что сокращение не берет параметр командной строки в качестве жала, но если параметр там, это используется в качестве имени файла. –  Timo 14.01.2014, 12:36

Теги

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