我有一个行数未知的文本文件.我需要随机抓取一些这些行,但我不希望有任何重复的风险.
我试过这个:
jot -r 3 1 `wc -l<input.txt` | while read n; do
awk -v n=$n 'NR==n' input.txt
done
Run Code Online (Sandbox Code Playgroud)
但这很丑陋,并不能防止重复.
我也试过这个:
awk -vmax=3 'rand() > 0.5 {print;count++} count>max {exit}' input.txt
Run Code Online (Sandbox Code Playgroud)
但这显然也不是正确的方法,因为我甚至不能保证获得max
线路.
我被卡住了.我该怎么做呢?
我有一个案例,我想使用文件中的输入作为printf()
awk 格式.当我在代码中的字符串中设置它时,我的格式化工作,但是当我从输入加载它时它不起作用.
这是问题的一个小例子:
$ # putting the format in a variable works just fine:
$ echo "" | awk -vs="hello:\t%s\n\tfoo" '{printf(s "bar\n", "world");}'
hello: world
foobar
$ # But getting the format from an input file does not.
$ echo "hello:\t%s\n\tfoo" | awk '{s=$0; printf(s "bar\n", "world");}'
hello:\tworld\n\tfoobar
$
Run Code Online (Sandbox Code Playgroud)
所以...格式替换工作(" %s
"),但不是像tab和换行符这样的特殊字符.知道为什么会这样吗?有没有办法"做某事"输入数据,使其可用作格式字符串?
更新#1:
作为进一步的示例,请考虑以下使用bash heretext:
[me@here ~]$ awk -vs="hello: %s\nworld: %s\n" '{printf(s, "foo", "bar");}' <<<""
hello: foo
world: bar
[me@here ~]$ awk '{s=$0; printf(s, "foo", "bar");}' <<<"hello: %s\nworld: …
Run Code Online (Sandbox Code Playgroud) 我有一个包含几千个文件的目录,命名为:
filename.ext
filename (1).ext
filename (2).ext
otherfile.ext
otherfile (1).ext
etc.
Run Code Online (Sandbox Code Playgroud)
大多数带有括号的文件都是原始文件的副本,但在某些情况下它们不是.
如何保留原始文件,删除重复文件,但不丢失不同的文件?
我知道我可以rm *\).ext
,但显然不能确保文件与原始文件匹配.
我正在使用OS X,所以我有一个md5
类似于md5sum
Linux的程序,尽管它将哈希放在行的末尾而不是开头.我以为我可以使用awk脚本获取输出md5 *.ext | awk 'some script'
,通过md5查找重复项,并删除它们,但命令行太长(bash: /sbin/md5: Argument list too long
).
我不知道在剧本中写什么.我想用这个来存储数组中的东西:
awk '{a[$NF]++} a[$NF]>1{sub(/).*/,""); sub(/.*(/,""); system("rm " $0);}'
Run Code Online (Sandbox Code Playgroud)
但这似乎总是删除我原来的.
我究竟做错了什么?我该怎么做?
谢谢.
所以...我知道我可以使用tac
或其他一些工具来反转文件中的行顺序,但是如何在其他维度中重新排序,即水平?我正在尝试使用以下awk脚本:
{
out="";
for(i=length($0);i>0;i--) {
out=out substr($0,i,1)}
print out;
}
Run Code Online (Sandbox Code Playgroud)
这似乎扭转了角色,但它是乱码,我不明白为什么.我错过了什么?
我在awk中这样做,但还有更好的东西吗? sed
, 也许?
这是一个例子.输入数据如下所示:
$ cowsay <<<"hello"
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Run Code Online (Sandbox Code Playgroud)
输出看起来像这样:
$ cowsay <<<"hello" | rev
_______
> olleh <
-------
^__^ \
_______\)oo( \
\/\) \)__(
| w----||
|| ||
Run Code Online (Sandbox Code Playgroud)
请注意,无论是使用rev
还是我自己的awk脚本,输出都是相同的.正如你所看到的,事情是相反的,但......它被破坏了.
我有一个愚蠢的大文本文件(即今天的40千兆字节),我想在没有排序文件的情况下过滤唯一的行.
该文件具有unix行结尾,并且所有内容都匹配[[:print:]]
.我尝试了以下awk脚本只显示唯一的行:
awk 'a[$0] {next} 1' stupid.txt > less_stupid.txt
Run Code Online (Sandbox Code Playgroud)
我的想法是,我通过引用其元素来填充数组,使用文件的内容作为键,然后跳过已经在数组中的行.但这有两个原因失败 - 首先是因为它莫名其妙地不起作用(即使是在小型测试文件上),其次是因为我知道在将整组唯一行加载到内存之前我的系统会耗尽内存通过awk.
搜索后,我发现这个答案建议:
awk '!x[$0]++'
Run Code Online (Sandbox Code Playgroud)
虽然这适用于小文件,但在读取整个文件之前也会耗尽内存.
什么是更好(即工作)的解决方案?我对任何事情都持开放态度,尽管我更倾向于使用我所知道的语言解决方案(bash&awk,因此标签).在尝试可视化问题时,我提出的最好的方法是存储一系列行校验和或MD5而不是行本身,但这只会节省一点空间并冒着校验和冲突的风险.
任何提示都会非常受欢迎.告诉我这是不可能的也是受欢迎的,所以我不想试图解决它.:-P
我有一个奇怪的问题:我的if和else语句都在执行.这是我的代码:
if ($sel_user['name'] != $name) {
$query = "UPDATE owner SET
..."
$result = mysql_query($query);
if (mysql_affected_rows() ==1) {
$query2 = "UPDATE queue_acl SET
..."
$result2 = mysql_query($query2);
if (mysql_affected_rows() ==1) {
$_SESSION['updates_occurred'] = true;
} else {
$_SESSION['updates_occurred'] = false;
}
}
}
if ($sel_user['orgId'] != $orgId) {
$query = "UPDATE ownerOrganization SET
..."
$result = mysql_query($query);
if (mysql_affected_rows() ==1) {
$query2 = "UPDATE queue_acl SET
..."
$result2 = mysql_query($query2);
if (mysql_affected_rows() ==1) {
$_SESSION['updates_occurred'] = true;
} else …
Run Code Online (Sandbox Code Playgroud) 我有一个任意偶数项目的列表.
输入数据:
Red
Orange
Yellow
Green
Blue
Violet
Run Code Online (Sandbox Code Playgroud)
输出数据:
Red -> Violet
Violet -> Orange
Orange -> Blue
Blue -> Yellow
Yellow -> Green
Green -> Red
Run Code Online (Sandbox Code Playgroud)
我的想法是,最高的项目与最低的项目匹配,我想有点从堆栈的两端弹出一些东西.一旦堆栈用完,最后剩下的匹配就是我们开始使用的任何东西.
我从这开始:
awk '{a[NR]=$0} END {for (i=1;i<=NR;i++) {printf("%s -> %s\n",a[i],a[NR-i+1])}}'
Run Code Online (Sandbox Code Playgroud)
它匹配从顶部到底部,但不"弹出".
这有可能在awk?
注意:我已经标记了这个"python",因为虽然我没有任何线索如何在python中执行此操作,但我非常想知道,如果它比awk答案更优雅,它将接受python答案.:-)
我有一个命令的stdout,我想以相反的顺序删除重复项.
也就是说,我希望重复的行从头开始而不是从末尾剥离.例如,从最后剥离我可能会使用经典技术awk
:
awk '!a[$0]++'
Run Code Online (Sandbox Code Playgroud)
虽然很棒,但它会删除错误的线条:
$ printf 'one\nfour\ntwo\nthree\nfour\n' | awk '!a[$0]++'
one
four
two
three
Run Code Online (Sandbox Code Playgroud)
我想最后一次four
打印即
$ printf 'one\nfour\ntwo\nthree\nfour\n' | <script>
one
two
three
four
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?在shell中有一个单线程的简单方法吗?
我将多个域的 SOA 数据存储在一个$INCLUDE
由区域文件获取的文件中。我编写了一个小的 sed 脚本,该脚本应该获取序列号,递增它,然后重新保存 SOA 文件。只要 SOA 文件格式正确(整个记录在一行上),一切都可以正常工作,但一旦记录被分割成多行,一切就会失败。
例如,这作为输入数据:
@ IN SOA dnsserver. hostmaster.example.net. ( 2013112202 21600 900 691200 86400 )
Run Code Online (Sandbox Code Playgroud)
但这并不:
@ IN SOA dnsserver. hostmaster.example.net. (
2013112202 ; Serial number
21600 ; Refresh every day, 86400 is 1 day
900 ; Retry refresh every 15 min
691200 ; Expire every 8 days
86400 ) ; Minimum TTL 1 day
Run Code Online (Sandbox Code Playgroud)
我喜欢评论,我想把事情传播出去。但我需要我的脚本能够找到序列号,以便我可以增加它并重写文件。
在单行上工作的 SED 是这样的:
SOA=$(sed 's/.*@.*SOA[^0-9]*//;s/[^0-9].*//' $SOAfile)
Run Code Online (Sandbox Code Playgroud)
但对于多线......我有点迷失了。我知道我可以使用 加入线路N
,但我怎么知道我是否需要这样做?我是否需要根据对原始文件所做的其他分析来编写单独的 sed …
我知道我可以做以下事情:
[[ $s =~ ^(re)(re)$ ]]
Run Code Online (Sandbox Code Playgroud)
BASH_REMATCH
用一系列括号表达式匹配来填充数组。但是有可能匹配未知数量的这些匹配项吗?例如,我得到以下信息:
s='abc defghi jklm nop '
[[ $s =~ ^([^ ]+ +)+$ ]]
declare -p BASH_REMATCH
Run Code Online (Sandbox Code Playgroud)
输出:
declare -ar BASH_REMATCH=([0]="abc defghi jklm nop " [1]="nop ")
Run Code Online (Sandbox Code Playgroud)
我认为BASH_REMATCH[1]
每次匹配时都会重写括号表达式。
我真正想看到的是:
declare -ar BASH_REMATCH=([0]="abc defghi jklm nop "
[1]="abc "
[2]="defghi "
[3]="jklm "
[4]="nop ")
Run Code Online (Sandbox Code Playgroud)
这可以在单个命令中实现吗?
我正在尝试制作倒数计时器脚本,该脚本需要几秒钟$1
,然后倒计时到零,显示当前剩余的秒数.
问题是,我在一个没有的嵌入式盒子上做这个,seq
或者jot
我知道可以生成我的数字列表的两个工具.
这是我在普通(非嵌入式)系统上工作的脚本:
#!/bin/sh
for i in $(/usr/bin/jot ${1:-10} ${1:-10} 1); do
printf "\r%s " "$i"
sleep 1
done
echo ""
Run Code Online (Sandbox Code Playgroud)
这适用于FreeBSD.如果我在Linux机器上,我可以用以下代码替换for
:
for i in $(/usr/bin/seq ${1:-10} -1 1); do
Run Code Online (Sandbox Code Playgroud)
为了同样的效果.
但如果我没有jot
OR,我该怎么办seq
?