我有一个包含多行的文件
10|EQU000000001|12345678|3456||EOMCO042|EOMCO042|31DEC2018|16:51:17|31DEC2018|SHOP NO.5,6,7 RUNWAL GRCHEMBUR MHIN|0000000010000.00|6761857316|508998|6011|GL
我必须使用字符计数将第11列拆分并替换为4个不同的列。
这是第11列,也包含多余的空格。
SHOP NO.5,6,7 RUNWAL GRCHEMBUR MHIN
这是我已经完成的
ls *.txt *.TXT| while read line
do
subName="$(cut -d'.' -f1 <<<"$line")"
awk -F"|" '{ "echo -n "$11" | cut -c1-23" | getline ton;
"echo -n "$11" | cut -c24-36" | getline city;
"echo -n "$11" | cut -c37-38" | getline state;
"echo -n "$11" | cut -c39-40" | getline country;
$11=ton"|"city"|"state"|"country; print $0
}' OFS="|" $line > $subName$output
完成
但是在执行第11列的回显时,它会修剪多余的空格,从而导致字符计数不匹配。有什么方法可以在不修剪空格的情况下进行回显?
实际输出
10|EQU000000001|12345678|3456||EOMCO042|EOMCO042|31DEC2018|16:51:17|31DEC2018|SHOP NO.5,6,7 RUNWAL GR|CHEMBUR MHIN|||0000000010000.00|6761857316|508998|6011|GL
预期产量
10|EQU000000001|12345678|3456||EOMCO042|EOMCO042|31DEC2018|16:51:17|31DEC2018|SHOP NO.5,6,7 RUNWAL GR|CHEMBUR|MH|IN|0000000010000.00|6761857316|508998|6011|GL
答案 0 :(得分:4)
到目前为止,我发现的最讨厌的编码方法是:
perl -F'\|' -lane '$F[10] = join "|", unpack "a23 A13 a2 a2", $F[10]; print join "|", @F'
这很简单:
|
上拆分每一行,并将字段放入@F
。$F[10]
),使用unpack
将其拆分为固定宽度的子字段(并修剪第二个字段(A
而不是a
的尾随空格))。|
结合来重组子字段。|
合并并打印来整行。我还没有对它进行基准测试,但是它可能比原始代码快得多,因为它是在一个过程中完成的,所以原始代码每条输入行产生多个shell和cut进程。
完整的解决方案会将其包装在shell循环中:
for file in *.txt *.TXT; do
outfile="${file%.*}$output"
perl -F'\|' -lane '...' "$file" > "$outfile"
done
或者如果您不需要修剪.txt
部分(并且您没有太多文件可容纳在命令行中):
perl -i.out -F'\|' -lane '...' *.txt *.TXT
这只是将每个输入文件foo.txt
的输出放在foo.txt.out
中。
答案 1 :(得分:2)
所有逻辑的纯bash实现
#!/usr/bin/env bash
shopt -s nocaseglob extglob
for f in *.txt; do
subName=${f%.*}
while IFS='|' read -r -a fields; do
location=${fields[10]}
ton=${location:0:23}; ton=${ton%%+([[:space:]])}
city=${location:23:12}; city=${city%%+([[:space:]])}
state=${location:36:2}
country=${location:38:2}
fields[10]="$ton|$city|$state|$country"
printf -v out '%s|' "${fields[@]}"
printf '%s\n' "${out:0:$(( ${#out} - 1 ))}"
done <"$f" >"$subName.out"
done
它比 pure awk慢(如果我做得好,大约10倍),但是比问题中提出的awk / shell组合要快得多。
进入使用的结构:
${varname%...}
和相关构造都是parameter expansion。特定的${varname%pattern}
构造会从pattern
中的值中删除varname
的最短匹配项,或者将%
替换为%%
时的最长匹配项。extglob
启用扩展的glob语法,例如+([[:space:]])
,它等效于正则表达式语法[[:space:]]+
。