【发布时间】:2011-05-09 06:38:20
【问题描述】:
如何在 bash 中删除字符后的所有文本,在本例中为冒号 (":")?我也可以去掉结肠吗?我不知道该怎么做。
【问题讨论】:
标签: bash
如何在 bash 中删除字符后的所有文本,在本例中为冒号 (":")?我也可以去掉结肠吗?我不知道该怎么做。
【问题讨论】:
标签: bash
egrep -o '^[^:]*:'
【讨论】:
egrep 是 grep 与 -E。这与普通的grep 没有区别。 -o 指示 grep 仅打印出与表达式匹配的那部分行。 ^ 将匹配锚定到一行的开头。 [^:]* 匹配零个或多个不是: 字符的字符。 : 匹配字符 :。
一个例子可能有用,但如果我理解正确的话,这会起作用:
echo "Hello: world" | cut -f1 -d":"
这会将Hello: world 转换为Hello。
【讨论】:
cut 有效,但我丹尼斯的回答更好、更灵活。有谁知道它是否会产生一个像cut 这样的新进程?
basename 和 cut)更好,请参阅下面丹尼斯的回答
cut 可以从标准输入中读取,因此尤其是当您需要处理很长的字符串(例如文件的内容)时会更好。
hello: world。这是一半的答案。
在 Bash(以及 ksh、zsh、dash 等)中,您可以使用带有 % 的参数扩展,这将删除字符串末尾的字符或 #,它将删除字符串开头的字符.如果您使用其中一个字符,最小的匹配字符串将被删除。如果将字符加倍,最长的将被删除。
$ a='hello:world'
$ b=${a%:*}
$ echo "$b"
hello
$ a='hello:world:of:tomorrow'
$ echo "${a%:*}"
hello:world:of
$ echo "${a%%:*}"
hello
$ echo "${a#*:}"
world:of:tomorrow
$ echo "${a##*:}"
tomorrow
【讨论】:
hello:world 这样的特定字符串之后的两个字符,使用${a%:*} 将变为hello:wo?
"${a##*:}" 只获得tomorrow =)
a='hello:world:of:tomorrow'; pattern=''^([^:]*:).*$'; [[ $a =~ $pattern ]];回声“${BASH_REMATCH[1]}”`。仅当有冒号时才匹配。如果您希望它是可选的,则必须使用不同的模式。 Bash 正则表达式(以及一般的正则表达式)的解释超出了这些 cmets 的范围。您可以找到讨论此问题的其他问题或发布您自己的问题。
$ echo 'hello:world:again' |sed 's/:.*//'
hello
【讨论】:
假设您有一个包含这种格式文件的路径:
/dirA/dirB/dirC/filename.file
现在您只需要包含四个“/”的路径。类型
$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-4 -d"/"
你的输出将是
/dirA/dirB/dirC
使用 cut 的好处是你还可以剪切最上面的目录以及文件(在这个例子中),所以如果你输入
$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-3 -d"/"
你的输出是
/dirA/dirB
虽然你可以从字符串的另一端做同样的事情,但在这种情况下,打字并没有多大意义
$ echo "/dirA/dirB/dirC/filename.file" | cut -f2-4 -d"/"
结果
dirA/dirB/dirC
在某些其他情况下,最后一种情况也可能会有所帮助。请注意,最后一个输出的开头没有“/”。
【讨论】:
去掉最后一个“:”之后的所有内容
grep -o '^.*:' fileListingPathsAndFiles.txt
如果你想删除最后一个“:”
grep -o '^.*:' file.txt | sed 's/:$//'
@kp123:您希望将: 替换为/(其中sed 冒号应为\/)
【讨论】:
我知道一些解决方案:
# Our mock data:
A=user:mail:password
$ echo $A | awk -v FS=':' '{print $1}'
user
$ echo ${A%%:*}
user
$ echo $A | sed 's#:.*##g'
user
$ echo $A | egrep -o '^[^:]+'
user
$ echo $A | cut -f1 -d\:
user
【讨论】: