Хотите извлечь часть имени файла до 5-го _?

У меня есть файл abc_asdfjhdsf_ckd_dfksfj_c_12345678_223344.txt . Я хочу, чтобы результат был как abc_asdfjhdsf_ckd_dfksfj_c.txt .

Использование sed

 $ echo abc_* | sed -E 's/(([^_]*_){5}).*/\1/; s/_$/.txt/' abc_asdfjhdsf_ckd_dfksfj_c.txt 

Как это работает:

  • s/(([^_]*_){5}).*/\1/

    Это фиксирует начало имени файла, вплоть до пятого _ , в группе 1 и удаляет остальную часть.

    Более подробно команды замены sed имеют форму s/old/new/ где old является регулярным выражением. В нашем случае регулярное выражение ([^_]*_){5} соответствует первым пяти частям. Мы помещаем это регулярное выражение в parens, (([^_]*_){5}) , так что первые пять частей сохраняются в группе 1, которые мы можем ссылаться как \1 . .* соответствует всем после первых пяти групп. Мы заменим все это только на первые пять групп, \1 .

  • s/_$/.txt/

    Это находит последнее оставшееся _ и заменяет его на .txt .

Использование awk

 $ echo abc_* | awk -F_ '{print $1,$2,$3,$4,$5 ".txt"}' OFS=_ abc_asdfjhdsf_ckd_dfksfj_c.txt 

Это использует _ как разделители полей ввода и вывода. Таким образом, это просто вопрос печати первых пяти полей, за которыми следует .txt .

Альтернативный подход: удаление двух последних частей

Вышеприведенные коды сохраняют первые пять частей и отбрасывают остальные. В выборке в вопросе есть семь частей, ни одна из которых не содержит в них периода. Если это всегда так , то альтернативный подход (tip tip: Costas) должен удалить последние две части:

 $ echo abc_* | sed -E 's/(_[^_]*){2}\././' abc_asdfjhdsf_ckd_dfksfj_c.txt 

Ссылаясь на исходный вопрос, который вы хотели переименовать, заканчивается файл:

 ls abc* abc_asdfjhdsf_ckd_dfksfj_c_12345678_223344.csv ls abc* | cut -d_ -f1-5 | awk '{print $1".txt";}' abc_asdfjhdsf_ckd_dfksfj_c.txt 
 for f in ./*_*_*_*_*_?*.txt do [ -e "$f" ] && printf %s.txt\\n "${f%"${f#*_*_*_*_*_?}"}" done 

Использование расширения параметра bash :

 for f in abc_*; do f="${f%_*}"; echo "${f%_*}.txt"; done 

Вывод:

 abc_asdfjhdsf_ckd_dfksfj_c.txt 

${f%_*} – шаблон расширения параметров, который будет содержать значение переменной f после удаления всего после последнего _ (включая).