Как получить список определенных строк в списке файлов, используя bash? - PullRequest
0 голосов
/ 23 апреля 2020

Возможно, заголовок не совсем описательный, но я не смог найти более краткий способ описать проблему.

У меня есть каталог, содержащий разные файлы с именем, которое выглядит, например, так:

{some text}2019Q2{some text}.pdf

Таким образом, имена файлов имеют где-то в названии год, за которым следует заглавная буква Q, а затем еще одно число. Другой текст может быть любым, но он не будет содержать ничего, что соответствует формату year-Q-number. Также не будет чисел непосредственно до или после этого формата.

Я могу что-то найти, чтобы получить это из одного имени файла, но мне действительно нужен «список», чтобы я мог сделать for-l oop через это в bash.

Итак, если мой каталог содержит файлы:

costumerA_2019Q2_something.pdf
costumerB_2019Q2_something.pdf
costumerA_2019Q3_something.pdf
costumerB_2019Q3_something.pdf
costumerC_2019Q3_something.pdf
costumerA_2020Q1_something.pdf
costumerD2020Q2something.pdf

Я хочу для l oop, которое выходит за 2019Q2, 2019Q3, 2020Q1 и 2020Q2 .

РЕДАКТИРОВАТЬ:

Это то, что я до сих пор. Он может извлечь подстроки, но у него все еще есть двойники. Так как я уже в л oop и я не вижу, как я могу удалить двойные.

find original/*.pdf -type f -print0 | while IFS= read -r -d '' line; do
   echo $line | grep -oP '[0-9]{4}Q[0-9]'
done

Ответы [ 2 ]

1 голос
/ 23 апреля 2020
# list all _filanames_ that end with .pdf from the folder original
find original -maxdepth 1 -name '*.pdf' -type f -print "%p\n" |
# extract the pattern
sed 's/.*\([0-9]{4}Q[0-9]\).*/\1/' |
# iterate
while IFS= read -r file; do
    echo "$file"
done

Я использовал -print %p, чтобы напечатать только имя файла, а не полный путь. GNU sed имеет опцию -z, которую вы можете использовать с -print0 (или -print "%p\0").

С тем, как вы хотели это сделать, если в ваших файлах нет новой строки в имени, есть не нужно l oop над списком в bash (как правило, старайтесь избегать while read line, это очень медленно):

find original -maxdepth 1 -name '*.pdf' -type f | grep -oP '[0-9]{4}Q[0-9]'

или с потоком с нулевым разделением:

find original -maxdepth 1 -name '*.pdf' -type f -print0 |
grep -zoP '[0-9]{4}Q[0-9]' | tr '\0' '\n'

Если вы хотите удалить повторяющиеся элементы из списка, перенаправьте его на sort -u.

0 голосов
/ 23 апреля 2020

Попробуйте, в bash:

~ > $ ls
costumerA_2019Q2_something.pdf  costumerB_2019Q2_something.pdf
costumerA_2019Q3_something.pdf  other.pdf
costumerA_2020Q1_something.pdf  someother.file.txt

~ > $ for x in `(ls)`; do [[ ${x} =~ [0-9]Q[1-4] ]] && echo $x; done;
costumerA_2019Q2_something.pdf
costumerA_2019Q3_something.pdf
costumerA_2020Q1_something.pdf
costumerB_2019Q2_something.pdf

~ > $ (for x in *; do [[ ${x} =~ ([0-9]{4}Q[1-4]).+pdf ]] && echo ${BASH_REMATCH[1]}; done;) | sort -u
2019Q2
2019Q3
2020Q1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...