Форматирование полей даты в файле с разделителями каналов

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

Позиционный параметр 0 - это всегда имя сценария (файла), а указанные аргументы начинаются с 1. Таким образом, вы можете получить первый аргумент, набрав $ 1 , второй - $ 2 и т. Д. на.

Например:

% foo () { printf '%s\n' "First: "$1" and Second: "$2"" ;}  

% foo spam egg
First: spam and Second: egg

Чтобы использовать его в операторе if , учитывая только первый аргумент $ 1 (то же самое касается и других аргументов):

if [ "$1" = "foo" ]; then
    ## Dome something
else
    ## Do something else
fi

Допустим, вы добавьте его в скрипт под названием foobar.sh . Теперь вы можете запустить скрипт как:

./foobar.sh foo
./foobar.sh bar
./foobar.sh blahblah

и значения $ 1 будут foo , bar , blahblah соответственно в трех случаи.

1
18.03.2019, 17:38
4 ответа

Как комментирует Кусалананда, вы можете просто манипулировать строками:

awk -F'|' -v OFS='|' '
    function format_date(d) { return substr(d,1,4) "/" substr(d,5,2) "/" substr(d,7) }
    { for (i = 7; i <= 9; i++) $i = format_date($i); print }
' file
2
27.01.2020, 23:22
awk -F'|' 'BEGIN {OFS="|"} {print $1,$2,$3,$4,$5,$6,strftime("%Y/%m/%d",$7),strftime("%Y/%m/%d",$8),strftime("%Y/%m/%d",$9)}' inputfile

Ключ здесь strftime(), который будет форматировать дату, указанную во втором параметре, используя строку формата в первом параметре:

$ echo "1552924174" | awk '{print strftime("%Y/%m/%d", $1) }'
2019/03/18

strftime()поддерживается GNU awkи mawk, но не BSD awk.

1
27.01.2020, 23:22

Вы можете сделать это, используя Perl, как показано:

Вход:

$ cat file
Location|1111|222222|333333|Doe|John|19900723|19900724|19900725

$ perl -lpe 's#\|\K([0-9]{8})(?=(?:(?:\|[0-9]{8}){0,2})$)#join "/", unpack "A4A2A2", $1#ge' file
Location|1111|222222|333333|Doe|John|1990/07/23|1990/07/24|1990/07/25

Пояснение:

  • -lустанавливает RS = ORS = "\n"
  • -pчитает входной файл в записи с установленным выше разделителем записей. Кроме того, выводит текущую запись на стандартный вывод перед чтением следующей.
  • -eприменяет код Perl, следующий за этой опцией, к каждой считываемой записи ($_).
  • regexнаходит 8-значные -числа, которым предшествует вертикальная черта и за которыми следуют не более двух соседей того же сорта, что и он сам, прежде чем он увидит конец строки. Они хранятся в захваченном виде в $1.
  • Теперь каждый захваченный $1распаковывается в соответствии с шаблоном A4A2A2, а затем эти шаблоны соединяются косой чертой.

Альтернативный:

$ perl -F'[|]' -pale '$_ = join "/", unpack "A4A2A2" for @F[-3..-1]; $_ = join "|", @F'
0
27.01.2020, 23:22

Я сделал следующим способом

`echo "Location|1111|222222|333333|Doe|John|19900723|19900724|19900725"| awk -F "|" '{$NF=substr($NF,1,4)"/"substr($NF,5,2)"/"substr($NF,7,2);$(NF-1)=substr($(NF-1),1,4)"/"substr($(NF-1),5,2)"/"substr($(NF-1),7,2);$(NF-2)=substr($(NF-2),1,4)"/"substr($(NF-2),5,2)"/"substr($(NF-2),7,2);print $0}'| sed "s/ /`|/g"

выход

echo "Location|1111|222222|333333|Doe|John|19900723|19900724|19900725"| awk -F "|" '{$NF=substr($NF,1,4)"/"substr($NF,5,2)"/"substr($NF,7,2);$(NF-1)=substr($(NF-1),1,4)"/"substr($(NF-1),5,2)"/"substr($(NF-1),7,2);$(NF-2)=substr($(NF-2),1,4)"/"substr($(NF-2),5,2)"/"substr($(NF-2),7,2);print $0}'| sed "s/ /|/g"


Location|1111|222222|333333|Doe|John|1990/07/23|1990/07/24|1990/07/25
0
27.01.2020, 23:22

Теги

Похожие вопросы