Как я могу сохранить только подстроку имен файлов из каталога без расширения файла? - PullRequest
0 голосов
/ 05 мая 2020

У меня есть каталог, из которого я читаю, и я хочу сохранить только представление даты в виде строки. Я близок к этому, хотя знаю, что, вероятно, есть более простой способ. Вот что у меня есть до сих пор:

#files are in the format of "THIS_20200420.csv" so I want only "20200420"
declare -a arr
declare -a arr2
FILES=test2/*.csv

for file in $FILES
do
    arr=(${arr[*]} "${file##*/}")
done

for i in "${arr[@]}"
do
   arr2+=$(echo $i | cut -c6-13)
done

for item in "${arr2[@]}"
do
    echo $item
done

вывод показывает, что массив имеет только один элемент, который представляет собой все объединенные строки:

20200110202001202020021920200220202004202020042220200110202001202020021920200220202004202020042220200219202002202020042020200422

Я бью головой о мой компьютер в этот момент.

Ответы [ 5 ]

0 голосов
/ 05 мая 2020

Вы можете добиться этого, используя al oop с awk:

$ for file in *.csv; do echo $file | awk -F '[^[:alnum:]]' '{print $2}'; done

-F '[^[:alnum:]]' указывает awk использовать символы без букв и цифр c в качестве разделителя.

Другой способ для этого нужно использовать расширение bash параметра оболочки, чтобы выводить только ту часть имени файла, которую вы хотите. Это, очевидно, работает только в том случае, если ваши имена файлов имеют согласованное форматирование:

$ for file in *.csv; do echo "${file:5:8}"; done

Я подумал, что было бы неплохо использовать расширение параметра bash, чтобы удалить нежелательный префикс и суффикс, но у вас не может быть вложенного расширения (afaict ) так что это лучшее, что я мог придумать:

$ for file in *.csv; do echo "$(tmp=${file%.csv}; echo ${tmp#THIS_})"; done
0 голосов
/ 05 мая 2020

Попробуйте это


declare -a arrayname=($(ls -1 test2/*.csv |  grep -o '[0-9]*'))

Демо:

$ls -1 *csv
THIS_20200420.csv
THIS_20200421.csv
THIS_20200422.csv
THIS_20200423.csv
THIS_20200424.csv
THIS_20200425.csv
THIS_20200426.csv
THIS_20200427.csv
THIS_20200428.csv
THIS_20200429.csv
THIS_20200430.csv
$declare -a arrayname=($(ls -1 *csv |  grep -o '[0-9]*'))
$echo ${arrayname[@]}
20200420 20200421 20200422 20200423 20200424 20200425 20200426 20200427 20200428 20200429 20200430
$echo ${arrayname[2]}
20200422
$
0 голосов
/ 05 мая 2020
arr=(
"THIS_20200420.csv"
"THIS_20200421.csv"
"THIS_20200422.csv"
"THIS_20200423.csv"
"THIS_20200424.csv"
"THIS_20200425.csv"
"THIS_20200426.csv"
"THIS_20200427.csv"
"THIS_20200428.csv"
"THIS_20200429.csv"
"THIS_20200430.csv" )
arr=( ${arr[@]//*_} )
arr=( ${arr[@]//.*} )
echo "arr: ${arr[@]}"

Объяснение:

arr=( ${arr[@]//*_} ) будет соответствовать всем символам до '_' для каждого элемента и заменять их пустой строкой.

arr=( ${arr[@]//.*} ) будет соответствовать всем символам после '.' для каждого элемента и замените их пустой строкой.

Для получения дополнительной информации о расширении параметров хорошей ссылкой является Руководство TLDP по расширению параметров .

0 голосов
/ 05 мая 2020

Встречайте Cut ! Хороший друг Linux пользователей

for file in ./*.csv; do echo $file | cut -d "_" -f 2 | cut -d "." -f 1 ; done

Эта одна строка должна помочь!

Пример:

output

0 голосов
/ 05 мая 2020

Использовать массив для назначения файлов и раскрытия параметров.

#!/usr/bin/env bash

shopt -s nullglob

##: Save the files ending in *.csv in an array 
## so it expands properly, variable assignment does not expand the glob *
files=(test2/*.csv)

##: Remain only the files that end with .csv without the pathname, longest match
files=("${files[@]##*/}")

##: Remain only the file names without the .csv extention
files=("${files[@]%.csv}")

##: Remain only the filename after the _ from the beginning, shortest match.
files=("${files[@]#*_}")

printf '%s ' "${files[@]}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...