我的源csv文件是Tab分隔我要将其转换为管道(|)分隔文件。 这是一些示例记录。
Loan_Name Current_Data_Status Mortgage_Loan_Seller
Market Basket RECM-PS Transfer Underwriters
我在sed
命令下面尝试过。
sed -i 's/\t/|/g' Test.csv
它正在将标签转换为|
,但它会在每行的末尾添加额外的|
。以下是我得到的输出。
Loan_Name|Current_Data_Status|Mortgage_Loan_Seller| |
Market Basket|RECM-PS Transfer|Underwriters| |
理想的输出应该是。
Loan_Name|Current_Data_Status|Mortgage_Loan_Seller
Market Basket|RECM-PS Transfer|Underwriters
请建议任何其他方法来实现这一目标。
答案 0 :(得分:4)
看起来你最后有两个标签。此外,仅供参考,tr
对于此类任务而言非常优雅。
cat Test.csv | sed -E 's/\t+$//g' | tr '\t' '|'
此命令首先删除任何尾随选项卡。注意-E适用于Ubuntu类型的unix,它可能是-r在bsd / MacOS上。
答案 1 :(得分:2)
一个简单的方法:删除所有尾随空格(包含选项卡),然后运行简单的正则表达式。
有两个选项,具体取决于有空字段时所需的输出。
用管道替换每个标签。在这种情况下,如果有一个空字段,我们将有两个彼此相邻的管道。这样我们就可以保持该字段,即使它是空的。
perl -lne 's/\s*$//; s/\t/|/g; print' Test.csv
用一个管道替换所有连续标签。在这种情况下,如果有空字段,它们将完全消失。这样我们就可以完全删除空字段。只有一根管子。
perl -lne 's/\s*$//; s/\t+/|/g; print' Test.csv
区别在于\t
和\t+
- \t
与标签匹配,+
表示任意数量(至少一个)。
\t
精确匹配一个标签(并用管道替换它)。因此,如果彼此相邻的两个选项卡每个都被管道替换。 \t+
匹配一个标签,或两个,或三个(连续的)...并用一个管道替换所有标签。另一种方法:使用Perl的split
来摆脱尾随的东西
perl -lne 'print join "|", grep { not /^\s*$/ } split /(\t\s*)+/' Test.csv
split
会丢弃任何尾随的空字段,因此我们首先拆分。由于在这个数据中,尾随字段也可能有空格,我们需要\t\s*
,因为这可能会导致我们过滤带空格的额外字段。然后join
得到一个干净的列表,用管道按要求放在一起。要覆盖原始文件,请添加-i
。
答案 2 :(得分:1)
您可以使用perl
perl -p -e 's/\t+/|/g' <Test.csv >Test.txt
如果要删除最后一个分隔符
perl -p -e 's/\t+/|/g' <Test.csv | sed -e 's/|$//' >Test.txt
答案 3 :(得分:1)
使用GNU sed:
(N3337) [class.temporary]/3:
在用sed ':a;s/[\t ]*$//;Ta;s/\t/|/g' Test.csv
替换\t
之前删除尾随标签/空格。
答案 4 :(得分:1)
这可能适合你(GNU sed):
sed 's/\>\t\</|/g' file
这会将单词之间的标签转换为管道。但是它不会转换相邻的标签,即空字段。
sed 's/\>\t\</|/g;s/\t//g' file
将删除剩余的标签。
sed 'y/\t/|/;s/\(\s*|\s*\)\+$/' file
将标签转换为管道并从行尾移除一个或多个管道(由可选空格分隔)。
答案 5 :(得分:0)
awk '{sub(/e Current_Data_Status M/,"e|Current_Data_Status|M")}{sub(/t RECM-PS Transfer U/,"t|RECM-PS Transfer|U")}NF{print}' file
Loan_Name|Current_Data_Status|Mortgage_Loan_Seller
Market Basket|RECM-PS Transfer|Underwriters