shell脚本中的awk

shell脚本中的awk
#
# Script Name : extract_filename.ksh
#
#!/bin/ksh

FILE_TO_SPLIT="CR_WKLY_Sales_SC_ON.TXT"
FILE_TO_SPLIT_NEW=$(awk FILE_TO_SPLIT_AWK="$FILE_TO_SPLIT" -F'[_.]' '{print $1"_"$3"_"$4"_"$5}')
echo "$FILE_TO_SPLIT_NEW"

以下命令在 unix 命令提示符下运行良好并获得所需的输出

echo "CR_WKLY_Sales_SC_NC.txt" | awk -F'[_.]' '{print $1"_"$3"_"$4"_"$5}'

在此输入图像描述

我正在尝试提取CR_Sales_SC_ON.TXT通过从文件名中删除“WKLY”,上面的脚本中做错了什么......?

有没有其他更好的办法来抑制王克利字符串来自CR_WKLY_Sales_SC_ON.TXTshell脚本中的字符串..?

WKLY只是为了展示我的示例,它可以是任何内容,我们的要求是在第一次出现“ _”(下划线)和第二次出现“ _”(下划线)之间提取抑制字符串。

例如。

CR_MNTHLY_In2_SC_NC.txt
CR_WKLY_Sales_ST_NC.txt
CR_YRLY_In2_ST_NC.txt
CR_DLY_ITr_SC_NC.txt

期望的输出应该是

CR_In2_SC_NC.txt
CR_Sales_ST_NC.txt
CR_In2_ST_NC.txt
CR_ITr_SC_NC.txt

答案1

我假设您也想删除其中一个下划线。这是一个使用以下解决方案sed

$ echo CR_WKLY_Sales_SC_ON.TXT | sed 's/WKLY_//'
CR_Sales_SC_ON.TXT

答案2

awk强制性的 ?

sed使用直观替换来适合该任务

sed -e 's/\(^[^_]*\)_[^_]*\(.*\)/\1\2/' u
CR_In2_SC_NC.txt
CR_Sales_ST_NC.txt
CR_In2_ST_NC.txt
CR_ITr_SC_NC.txt

u你的文件(或输入)在哪里。

对于单个变量

FILE_TO_SPLIT_NEW=$(echo "$FILE_TO_SPLIT" | sed -e 's/\(^[^_]*\)_[^_]*\(.*\)/\1\2/')

sed 的语法:

  • /\(^[^_]*\)_[^_]*\(.*\)/此过滤器pattern1_pattern2_rest,其中pattern 和rest 没有_
    • [^_]*代表“除了下划线之外的任何内容,任意次数”。
    • 模式1和其余分配给变量\(...\)
  • /\1\2/展开变量
  • -e可以省略单个替换

答案3

我认为您的实际问题是如何将要转换的字符串传递给awk脚本中的调用。这就是 @terdon 质疑这FILE_TO_SPLIT_AWK="$FILE_TO_SPLIT"意味着什么的原因。

正确的方法之一就像

FILE_TO_SPLIT_NEW=$(echo "$FILE_TO_SPLIT" | awk -F'[_.]' '{print $1"_"$3"_"$4"_"$5}')

另外,由于您希望文件名后缀(在您的情况下.txt)保留在输出中,而您的命令行示例却没有,因此您应该

  • .要么不在字段分隔符列表中包含句点,要么

  • 还打印最后一个字段

所以要么

  • awk -F'_' '{print $1"_"$3"_"$4"_"$5}', 或者

  • awk -F'[_.]' '{print $1"_"$3"_"$4"_"$5"."$6}'

无论如何,如果您想独立于“_”分隔字段的实际数量并且只想计算第二个字段,则以下示例应该有效:

FILE_TO_SPLIT_NEW=$(echo "$FILE_TO_SPLIT" | awk '{match($0,"^([^_]+)_([^_]+)_([[:print:]]*)$",a); print a[1]"_"a[3]}')

附录

如果您想避免由于使用管道而进行上下文切换,您可以首先将要转换的文件名写入临时文件,然后awk对该文件而不是内存中的变量进行操作。

echo $FILE_TO_SPLIT > tmpfile.txt
FILE_TO_SPLIT_NET=$(awk '{match($0,"^([^_]+)_([^_]+)_([[:print:]]*)$",a); print a[1]"_"a[3]}' tmpfile.txt)

然而,然后(当然取决于您的特定用例)您可能希望将所有“原始”文件名写入一个文件,awk对该文件进行操作,并逐行读取结果以处理所有转换后的文件名。

答案4

也许

cut -d_ -f1,3- file

设置分隔符-d_和输出-f字段 1 和 3 及以上1,3-

输出

CR_In2_SC_NC.txt
CR_Sales_ST_NC.txt
CR_In2_ST_NC.txt
CR_ITr_SC_NC.txt

在变量/字符串上

cut -d_ -f1,3- <<<"CR_Banana_IN2_SC_NC.txt"

或者

echo "CR_Banana_IN2_SC_NC.txt" | cut -d_ -f1,3-

相关内容