Linux Centos 6-64
File1.txt
有几行这种格式:
/Text1/Text2/Text3:Text4
如何让文件Result.txt
包含如下所示的所有行?
Text2;Text4
PS::
转变为;
。
我想到两种方法可以做到这一点:
- 通过删除
/Text1/
修改就可以了/Text3
。:
;
- 或者读取第 2 和第 3 之间的内容
/
,然后Text2
读取:
其之后的内容Text4
并执行;Text4
。
因此最终结果文件Result.txt
将具有
Text2;Text4
两种方法都可以,但速度更快的方法更好。
PS:文本中可能有空格,符号和点,但文本中原始的分隔符始终/
/
/
:
不会出现在文本内的任何其他地方。
这必须在各行各业中完成File.txt
。
文件:
File1.txt
/Soccer.Teacher/Michael.John/Group1:monday-friday - 14h to 16h
/Basketball.Teacher/Susana.Stevens/Group2:tuesday-thursday-3pm-to-5pm
/Tennis.Teacher/Josh.Karen/Group3:monday-wednesday-5pm_to_7pm
ETC。
Result.txt
成为:
Michael.John:monday-friday - 14:00 to 16:00
Susana.Stevens:tuesday-thursday-3pm-to-5pm
Josh.Karen:monday-wednesday-5pm_to_7pm
ETC。
答案1
文本中可能有空格、符号和点,但文本中的原始分隔符始终
/
/
/
:
不会出现在文本内的任何其他地方。
不对。您举了一个例子这允许一种简单的方法:14:00 to 16:00
。我们暂时假设它是真的。
tr ':' '/' | cut -d '/' --output-delimiter=';' -f 3,5
tr
统一分隔符,然后cut
选择正确的字段。
笔记:
--output-delimiter
POSIX 不要求。如果你cut
不支持它,这是替代方案:tr ':' '/' | cut -d '/' -f 3,5 | tr '/' ';'
请注意,我们不能将其用作
tr ':' ';'
管道中的第一个命令(这会简化其余部分),因为您不能保证它;
不会出现在输入中(cut
如果出现则会感到困惑)。cut
采取字段 3 和 5(而不是 2 和 4),因为第一个分隔符之前的所有内容已经是字段 1(在您的情况下为空字符串)。
但是,如果只有第一个:
应该是分隔符,那么命令可能是:
sed 's|:|/|' | cut -d '/' --output-delimiter=';' -f 3,5
sed 's|:|/|'
将仅替换第一次出现的:
(与之相对sed 's|:|/|g'
,相当于我们原来的tr ':' '/'
)。
如果你不熟悉使用此类过滤器处理文件的标准方法,这是正确的语法(符合sed
POSIX 标准cut
):
< File1.txt sed 's|:|/|' | cut -d '/' -f 3,5 | tr '/' ';' > Result.txt
答案2
sed
这样做:
echo '/Text1/Text2/Text3:Text4' | sed -E 's/\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+):([a-zA-Z0-9]+)/\2;\4/'
-E
使用扩展正则表达式\/
使用转义字符来表示特定/
字符([a-zA-Z0-9]+)
定义让我们说单词模式地区。\2;\4
访问第二和第四区域部分。
根据您的上一版本:
sed -E 's/\/([^/]+)\/([^/]+)\/([^/:]+):([^/]+)$/\2;\4/' FileName
答案3
虽然不是最短/最快的解决方案,但可以完成工作并且易于理解:
#!/bin/bash
while read -r line; do
echo -n "$line" | cut -d "/" -f 3 | tr -d $'\n'
echo -n ";"
echo "$line" | cut -d ":" -f 2
done < "File1.txt"
-n
因为前两个echo
s 很重要,所以它们都放在一行中。
由于您的版本cut
不支持,-z
因此| tr -d $'\n'
需要删除 cut 的尾随换行符。