Tag Info

Hot answers tagged

22

why are there so many "sh compatible" shells The Bourne shell has been with us since 1977, released as part of Unix V7. Since pretty much every Unix and Unix-like system descends from V7 Unix — even if only spiritually — the Bourne shell has been with us "forever."1 The Bourne shell actually replaced an earlier shell, retronymed the ...


12

With tr, use the -s ("squeeze repeats") option: $ tr -s " " < file ID Name 1 a 2 b 3 g 6 f Or you can use an awk solution: $ awk '{$2=$2}1' file ID Name 1 a 2 b 3 g 6 f When you change a field in record, awk rebuild $0, takes all field and concat them together, separated by OFS, which is a space by default.


10

In any version of Bash on any system, yes. ~ as a term on its own is defined to expand to: The value of $HOME so it will always be the same as whatever $HOME is to the current shell. There are several other tilde expansions, such as ~user for user's home directory, but a single unquoted ~ on its own will always expand to "$HOME". Note that the ...


9

Assuming that 20000-words.txt is already in the format of one word per line, do: grep -vFf 20000-words.txt 50000-lines.txt >50000-filtered-lines.txt The -f argument to grep tells it to read patterns from a file, one pattern per line, instead of taking them as command line arguments. The -F argument to grep tells it that the patterns should be used as ...


8

"sh compatible" refers to POSIX sh, the basic shell that is required to exist on all compatible systems. A sh-compatible script should work on any POSIX-compatible machine. The reason it's necessary to say so is that commonly /bin/sh is a symlink to /bin/bash, which has let some Bashisms slip into scripts that declare themselves to use sh with #!/bin/sh. ...


7

What's important to understand is that ~ expansion is a feature of the shell (of some shells), it's not a magic character than means your home directory wherever it's used. It is expanded (by the shell, which is an application used to interpret command lines), like $var is expanded to its value under some conditions when used in a shell command line before ...


6

You should use -v option of awk: awk -F',' -v accNum="$1" '$1 == accNum {print $3,$2}' With $1 in double quote, the shell will handle all its special character ( if has ) for you.


6

With the Perl rename tool (which is called rename on Debian and friends including Ubuntu, it may be prename elsewhere): rename -n 's/(?<!\.)jpg$/.jpg/' * # -n makes it show you what it'll do, # but not actually do it. Remove the -n to # actually rename To break down that patter: the ...


6

The backticks (``) are command substitution: they are replaced by the result of running the command inside the backticks. Here they run whoami, which prints your username. The - after su makes su run a login shell: a login shell will read certain environment configuration from scratch, among other things. By default it would just run the user's shell as an ...


5

You just have to read it left to right: > file --> redirect all thing from stdout to file.(You can imagine you have a link, point-to-point from stdout to file) 2>&1 --> redirect all thing from stderr to stdout, which is now pointed to file. So conclusion: stderr --> stdout --> file You can see a good reference here.


5

An ugly way of doing this (i.e. causing a function call in shell based on output from awk) could look like this: awk -F '\t' ' FNR < 2 {next} FNR == NR { for (i=2; i <= NF; i++) { if (($i == 1) || ($i == 4)) printf "retrieve %s\n", $i if (($i == 2) || ($i == 2)) printf "retrieve2 ...


5

Just use column: column -t inputFile Output: ID Name 1 a 2 b 3 g 6 f


5

Shell scripts are normally treated as if they were the same as any other kind of executable file, such as binaries, Python scripts, Perl scripts, or any other kind of script. They have a shebang at the top that directs the kernel to execute them through the shell. They are expected to be invoked the same way as any other command. As such, a new shell is ...


4

For passing file paths as arguments to a command, find does this on its own with its -exec option without any xargs trickery: find /home/user -name '*.csv' -exec yourcommand '{}' + That will find every file called *.csv in /home/user and then execute yourcommand /home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv ... with all of the found files as ...


4

Try: $ echo 28fe2baadbe8da32ed0b99c69b11c01b2d141bc5b732b81e0960086de52fc891 | awk '{sub(/\r/,"")} length == 64 && /^[[:xdigit:]]+$/' 28fe2baadbe8da32ed0b99c69b11c01b2d141bc5b732b81e0960086de52fc891 or use perl instead. Include newline: perl -ne 'print if length == 64 and /^[[:xdigit:]]+$/' Exclude newline: perl -nle 'print if length == 64 ...


4

You're backgrounding the application, and the application is generating output. Your prompt is still there, it just has extra stuff being shown. For example: $ ( sleep 1 && echo hello ) & [1] 24764 $ █ And then after a 1 second delay, I get: $ ( sleep 1 && echo hello ) & [1] 24764 $ hello █ The echo is just writing output to ...


3

Who needs a program (other than the shell)? while read a b do echo "$a $b" done < f1.txt If you want the values in the second column to line up, as in polym’s column answer, use printf instead of echo: while read a b do printf '%-2s %s\n' "$a" "$b" done < f1.txt


3

A quick hack with perl: perl -wlne 'print for(/<.*?>/g)' file.html But for a serious solution you should use a tool that really understands html/xml.


3

While sed is a very useful and versatile tool, you're not using it properly. It's best used to match and substitute strings in text files; it can't directly rename files on the filesystem. This task is better suited for a bash one-liner (assuming that's your shell). To rename something like . filejpg to file.jpg, use this: find . -name '. *' -print0 | ...


3

How about a whole-line grep grep -qxE '[[:xdigit:]]{64}' myid.id && echo "yes" or (not sure about this one) bash-specific IFS= read -r id < myid.id [[ ${#id} -eq 64 ]] && [[ $id =~ [[:xdigit:]]{64} ]] && echo "yes"


2

Your script already practically does the job without any awk at all: while IFS=, read -r num last first do [ $((num==accountNum)) -eq 1 ] && printf '%s.%s\n' "$first" "$last" done < Accounts I'm not suggesting that this is a better or more efficient solution than using awk alone, but if you want the while...read loop, this ...


2

You have: accountNum=$1 awk -F',' '{ if($1==accountNum) { print $3.$2 } }' Accounts How does the shell variable accountNum get into awk? It doesn't: you need to provide its value to awk explicitly. You can use: awk -F',' '{ if($1=='"$accountNum"') { print $3.$2 } }' Accounts which leaves single quotes and has the shell substitute the value of its ...


2

If you just installed it it's likely that your shell has cached the old path. Use: hash -r to clear the command hash table and then try running the command again.


2

I would probably do something like this: # as proposed by csny, only open file quickly (file is closed after with statement) with open('sysctl.conf') as infile: infilelines = infile.readlines() outfile = open('sysctl.conf.new', 'w') replacements = {'Net.ipv4.icmp_echo_ignore_all' :'1', 'Net.ipv4.icmp_echo_ignore_broadcasts' :'1', ...


2

Just pipe through a while loop: git diff --name-only develop | grep coffee$ | while IFS= read -r file; do ./node_modules/.bin/coffeelint "$file" done


2

Using an actual html parser isn't that hard: perl -MHTML::Parser -E ' $handler = sub {say "<".shift.">"}; HTML::Parser->new(start_h => [$handler,"tag"], end_h => [$handler,"tag"]) ->parse_file(shift @ARGV) ' file.html <html> <head> <title> </title> </head> <body> </body> ...


2

What is it you are missing? You seem to have understood everything. The > file sends the output to file and 2>&1 sends standard error to standard output. The final result is that both stderr and stdout are sent to file. To illustrate, consider this simple Perl script: #!/usr/bin/env perl print STDERR "Standard Error\n"; print STDOUT "Standard ...


2

dialog is a great tool for what you are trying to achieve. Here's the example of a simple 3-choices menu: dialog --menu "Choose one:" 10 30 3 \ 1 Red \ 2 Green \ 3 Blue The syntax is the following: dialog --menu <text> <height> <width> <menu-height> [<tag><item>] The selection will be sent to stderr. ...


1

To do it without grep and assume that you don't have duplicated lines, you can: $ sort 20000-words.txt 50000-lines.txt | uniq -u or: $ comm -23 <(sort 50000-lines.txt) <(sort 20000-words.txt)


1

OP and I worked through this; see comments & chat for details. First, to find the problem process and location, this line in /etc/init/mountall-shell.conf /sbin/sulogin was changed to /usr/bin/ltrace -S -f -o /root/sulogin-ltrace.log /bin/sulogin Excerpt from log: 837 crypt("password", "x") = nil 837 strcmp(nil, "x" <no return ...> 837 --- ...



Only top voted, non community-wiki answers of a minimum length are eligible