使用 bash 中的 IFS 使用 \r\n 拆分字符串
Split string using \r\n using IFS in bash
我想在 bash 中拆分包含 \r\n 的字符串,但 return 和 \n 出现问题。谁能给我提示不同的 IFS?我也试过 IFS=' |\'
输入:
projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02
代码:
IFS=$'\r'
inputData="projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02"
for line1 in ${inputData}; do
line2=`echo "${line1}"`
echo ${line2} //Expected one by one entry
done
预计:
projects.google.tests.inbox.document_01
projects.google.tests.inbox.document_02
projects.google.tests.inbox.global_02
关注 awk 可以帮助您解决问题。
awk '{gsub(/\r\n/,RS)} 1' Input_file
或
echo "$var" | awk '{gsub(/\r\n/,RS)} 1'
输出如下。
projects.google.tests.inbox.document_01
projects.google.tests.inbox.document_02
projects.google.tests.inbox.global_02
说明: 使用 awk
的 gsub
实用程序用于全局替换及其方法是gsub(/regex_to_be_subsituted/,variable/new_value,current_line/variable)
,所以这里我给\r\n
(这里要注意的一点我在这里转义\
,这意味着它将把它当作一个文字字符)和RS
(当前行记录分隔符,默认为新行)。然后 1
意味着,awk
作用于条件和动作的方法,所以通过提及 1
我将条件设置为 TRUE 并且没有给出动作,因此将发生当前的默认动作打印。
编辑: 使用变量,您可以按以下方式使用。
var="projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02"
echo "$var" | awk '{gsub(/\r\n/,RS)} 1'
projects.google.tests.inbox.document_01
projects.google.tests.inbox.document_02
projects.google.tests.inbox.global_02
inputData=$'projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02'
while IFS= read -r line; do
line=${line%$'\r'}
echo "$line"
done <<<"$inputData"
注:
- 字符串定义为
string=$'foo\r\n'
,而不是 string="foo\r\n"
。后者不会将实际的 CRLF 序列放入您的变量中。有关此语法的说明,请参阅 bash-hackers' wiki 上的 ANSI C-like strings。
${line%$'\r'}
是一个 parameter expansion,它从变量 line
的内容末尾剥离文字回车 return,如果存在的话。
- BashFAQ #1 中详细描述了逐行读取输入流(此处使用)的做法。与使用
for
进行迭代不同,它不会尝试将您的数据扩展为 glob。
我想在 bash 中拆分包含 \r\n 的字符串,但 return 和 \n 出现问题。谁能给我提示不同的 IFS?我也试过 IFS=' |\'
输入:
projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02
代码:
IFS=$'\r'
inputData="projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02"
for line1 in ${inputData}; do
line2=`echo "${line1}"`
echo ${line2} //Expected one by one entry
done
预计:
projects.google.tests.inbox.document_01
projects.google.tests.inbox.document_02
projects.google.tests.inbox.global_02
关注 awk 可以帮助您解决问题。
awk '{gsub(/\r\n/,RS)} 1' Input_file
或
echo "$var" | awk '{gsub(/\r\n/,RS)} 1'
输出如下。
projects.google.tests.inbox.document_01
projects.google.tests.inbox.document_02
projects.google.tests.inbox.global_02
说明: 使用 awk
的 gsub
实用程序用于全局替换及其方法是gsub(/regex_to_be_subsituted/,variable/new_value,current_line/variable)
,所以这里我给\r\n
(这里要注意的一点我在这里转义\
,这意味着它将把它当作一个文字字符)和RS
(当前行记录分隔符,默认为新行)。然后 1
意味着,awk
作用于条件和动作的方法,所以通过提及 1
我将条件设置为 TRUE 并且没有给出动作,因此将发生当前的默认动作打印。
编辑: 使用变量,您可以按以下方式使用。
var="projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02"
echo "$var" | awk '{gsub(/\r\n/,RS)} 1'
projects.google.tests.inbox.document_01
projects.google.tests.inbox.document_02
projects.google.tests.inbox.global_02
inputData=$'projects.google.tests.inbox.document_01\r\nprojects.google.tests.inbox.document_02\r\nprojects.google.tests.inbox.global_02'
while IFS= read -r line; do
line=${line%$'\r'}
echo "$line"
done <<<"$inputData"
注:
- 字符串定义为
string=$'foo\r\n'
,而不是string="foo\r\n"
。后者不会将实际的 CRLF 序列放入您的变量中。有关此语法的说明,请参阅 bash-hackers' wiki 上的 ANSI C-like strings。 ${line%$'\r'}
是一个 parameter expansion,它从变量line
的内容末尾剥离文字回车 return,如果存在的话。- BashFAQ #1 中详细描述了逐行读取输入流(此处使用)的做法。与使用
for
进行迭代不同,它不会尝试将您的数据扩展为 glob。