Отримайте один елемент рядка шляху за допомогою bash


9

У мене є файл ASCII, що містить файлові шляхи, які я читаю, запускаючи:

while read p; do echo $p; done < filelist.txt

Файл містить доріжки файлів із таким малюнком:

./first/example1/path
./second/example1/path
./third/example2/path

Як я можу отримати конкретну частину рядка шляху (від /до /), наприклад, мені потрібно отримати висновок, який друкує:

first
second
third

а також

example1
example1
example2

Я впевнений, що є спосіб зробити це за допомогою регулярних виразів sed, але я не знайомий з цим.

Відповіді:


17

Використання cut:

$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path

$ cut -d/ -f2 filelist.txt 
first
second
third

$ cut -d/ -f3 filelist.txt 
example1
example1
example2

-d/Встановлює роздільник стовпчиків для /і -f2вибирають 2 - й стовпець.

Можна, звичайно, також використовувати cutкоманду Bash замість імені файлу або даних даних у команді:

cut -d/ -f3 $MyVariable
echo ./another/example/path | cut -d/ -f3

Використання | cut -d/ -f3 в трубі зробило свою справу. Дякую! Це повне командування зараз: while read p; do echo $p; done < filelist.txt | cut -d/ -f3
mcExchange

3
@mcExchange Немає підстав використовувати це під час циклу. Це набагато простіше просто зробити cut -d/ -f3 filelist.txt
Monty Harder

1
Крім того, ухилення від цього часу дозволяє уникнути проблем із котируванням, і не вийде з ладу з новими рядками у назвах файлів.
Volker Siegel

10

Ви можете зробити це безпосередньо у своїй readкоманді, використовуючи IFSзмінну, наприклад

$ while IFS=/ read -r p1 p2 p3 r; do echo "$p2"; done < filelist.txt 
first
second
third

5

Можна використовувати awk

pilot6@Pilot6:~$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path

pilot6@Pilot6:~$ awk -F "/" '{print $2}' filelist.txt
first
second
third

pilot6@Pilot6:~$ awk -F "/" '{print $3}' filelist.txt
example1
example1
example2

3

Якщо ми хочемо будь-який елемент шляху, найкраще використовувати те, що може розбити рядок на поля, наприклад , ,, або . Однак, також може виконувати роботу з підстановкою параметрів, використовуючи заміну шаблону та перекидаючи все в масив.

$> echo ${FILE//\//\ }                                                         
sys class backlight intel_backlight brightness
$> ARRAY=( ${FILE//\//" " } )                                                  
$> echo ${ARRAY[2]}
backlight

$> FILE="./dir1/dir2/file.txt"                                                 
$> ARRAY=( ${FILE//\/" "} )
$> echo ${ARRAY[@]}                                                            
. dir1 dir2 file.txt
$> echo ${ARRAY[1]}
dir1

Тепер у нас є масив елементів, зроблений із шляху. Зауважте, що якщо шлях містить пробіли, він може включати зміни внутрішнього роздільника поля IFS.


1

Bash і cutшлях, але альтернатива за допомогою Perl:

perl -F/ -lane 'print(@F[1])' filelist.txt

для другого /-делімітованого поля і

perl -F/ -lane 'print(@F[2])' filelist.txt

для третього /-делімітованого поля.

  • -l: дозволяє автоматичну обробку ліній. Він має два окремих ефекту. По-перше, він автоматично підключає $ / (роздільник вхідних записів) при використанні з -n або -p. По-друге, він призначає $ \ (розділювач записів вихідних даних) мати значення octnum, щоб будь-які оператори друку знову додавали цей роздільник. Якщо octnum опущено, встановлює $ \ поточне значення $ /.
  • -a: увімкнює режим автошпліту при використанні з -n або -p. Неявна розділена команда для масиву @F виконується як перше, що знаходиться всередині неявного циклу в той час, як цикл виробляється -n або -p.
  • -n: змушує Perl взяти на себе наступний цикл навколо вашої програми, що змушує ітерацію аргументів імені файлу дещо нагадувати sed -n або awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: може використовуватися для введення одного рядка програми;

  • print(@F[N]): друкує N-е поле.
% cat filelist.txt 
./first/example1/path
./second/example1/path
./third/example2/path
% perl -F/ -lane 'print(@F[1])' filelist.txt
first
second
third
% perl -F/ -lane 'print(@F[2])' filelist.txt
example1
example1
example2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.