Я пытаюсь обновить существующий файл CSV с помощью сценария оболочки. Существует столбец ASOF_DATE, в котором я пытаюсь заменить его значение текущей датой. Сценарий оболочки, который я использую, мне не помогает, он возвращает пустые значения для столбца ASOF_DATE; можешь понять, что не так?
Пример входных данных:
ASOF_DATE,CUSIP,Current Face,Market Value
'04/08/2024',BENRDUZU0,-400000000
'04/08/2024',BENRDUZR7,-300000000
'04/08/2024',BENRE4H37,-225000000
'04/08/2024',BENRDUYW7,-250000000
Ниже приведен сценарий оболочки, который я использую:
#!/bin/bash
if [ "$#" -lt 1 ]; then
echo "Argument is missing"
exit 1
fi
asOnDate=$1
FILE_PATH=/awsdatalake/data/inbound/file/SRC_TPGCF/
if [ ! -f ${FILE_PATH}CFG_ANALYTICS_*.csv ]
then
echo "File does not exist"
exit 2
else
echo "File found."
for file in ${FILE_PATH}CFG_ANALYTICS_*.csv
do
echo "$file"
awk -v date = "$asof_date" -F, 'BEGIN {OFS = ","} {if (NR==1) {print $0} else {if (NR>1) {$1=date; print}}}' "$file" > temp_file && mv temp_file "$file"
echo "Current date $asof_date added to the ASOF_DATE column in $file_path"
done
fi
Кстати, записывайте диагностические сообщения в стандартную ошибку с помощью >&2
, но, возможно, не делайте echo
так много.
if [ ! -f ${FILE_PATH}CFG_ANALYTICS_*.csv ]
не в том, как определить, содержит ли каталог хотя бы 1 файл. Погуглите это.
shellcheck.net предупредит вас об этом, о проблеме, о которой вы спрашиваете, и о других проблемах.
пожалуйста, обновите вопрос с ожидаемым результатом; также укажите, что вы используете в качестве «текущей даты» (например, for current date I am using 7 May 2024
)
что такое asonDate
? это опечатка и должно быть так asof_date
?
asof_date
— это просто неинициализированная переменная, поэтому вы заменяете поле… ничем. Но добавить переменную легко:
:
awk -v date = "$(date +%F)" -F, 'BEGIN {OFS = ","}
NR>1 {$1=date } 1' "$file" > temp_file &&
mv temp_file "$file"
:
Вы заметите, что я также немного переработал ваш Awk-скрипт. Есть много других проблем с вашим скриптом оболочки, но я отложу https://shellcheck.net/ для диагностики.
Если вы хотели использовать (иначе неиспользуемую переменную) asOnDate
, то вы могли бы использовать $1
напрямую.
Это можно сделать, используя приведенный ниже сценарий оболочки, awk -F',' -v OFS=',' 'BEGIN {IGNORECASE=1} {if (NR>1) $1 = "'"$current_date"'"} 1' $ файл > temp && mv temp $file
Похоже, ОП хотел бы date = "'$(date +%F)'"
с окружающими одинарными кавычками.
Ваш обходной путь с '"$current_date"'
довольно хрупкий; передача строки с помощью -v
гораздо более надежна. Итак, в целом ваша первоначальная попытка была лучше, но, конечно, требовалась правильная переменная.
@EdMorton Или, может быть, $1 = "\047" date "\047"
. Как уже отмечалось в другом месте, одинарные кавычки в данных CSV — это странно и, вероятно, просто неправильно.
Было бы немного эффективнее добавлять кавычки один раз, когда date
заполняется, а не каждый раз, когда они используются в каждой строке ввода, но кто знает, действительно ли ОП этого хочет...
Я бы использовал GNU AWK
для этой задачи следующим образом: пусть file.csv
контент будет
ASOF_DATE,CUSIP,Current Face,Market Value
'04/08/2024',BENRDUZU0,-400000000
'04/08/2024',BENRDUZR7,-300000000
'04/08/2024',BENRE4H37,-225000000
'04/08/2024',BENRDUYW7,-250000000
затем
awk -i inplace 'BEGIN{FS=OFS = ",";currdate=strftime("\047%d/%m/%Y\047")}FNR>1{$1=currdate}{print}' file.csv
приводит к тому, что контент file.csv
(при выполнении 7 мая 2024 года) становится
ASOF_DATE,CUSIP,Current Face,Market Value
'07/05/2024',BENRDUZU0,-400000000
'07/05/2024',BENRDUZR7,-300000000
'07/05/2024',BENRE4H37,-225000000
'07/05/2024',BENRDUYW7,-250000000
Пояснение: я использую -i inplace
, чтобы указать GNU AWK
изменить предоставленный файл (или файлы). Внутри BEGIN
я сообщаю GNU AWK
, что разделителем полей и разделителем выходных полей является запятая, и использую функцию времени strftime для подготовки текущей даты в формате dd/mm/YYYY
(я предполагаю, что вы используете формат с прямым порядком байтов, отрегулируйте в соответствии с ним, если вам нужен средний порядок байтов). формат даты), заключенный в '
, поскольку его нельзя поместить в команду GNU AWK
, я использую escape-последовательность \047
. Если строка номера файла (FNR
) выше единицы, я устанавливаю в 1-м поле подготовленную дату. Я print
каждую строчку. Обратите внимание, что я использую FNR
, а не NR
, поэтому его можно использовать с несколькими строками, например. баран file1.csv file2.csv file3.csv
вместо file.csv
(проверено в GNU Awk 5.1.0)
Использование одинарных кавычек вокруг первого поля странно. Стандартный CSV использует двойные кавычки вокруг цитируемых полей.