pipe fzf selection to text manipulation to zsh prompt (without executing) - zsh

Here's a function that executes a selected alias using fzf:
fa() {
eval $(alias | fzf | cut -d'=' -f2 | sd -p "'" '')
}
The problem is that sometimes you want to add more arguments to an alias rather than immediately execute it. Is this possible?

Solution using zsh:
fa() {
print -z $(alias | fzf | cut -d'=' -f2 | sd -p "'" '')
}

Related

reduction of stream of object does not work for me

I wrote several reductions, where I had array to begin with. But if I try to read raw data and transform each line into object, I don't have much luck reducing them together
echo -e "1\n2\n\n\n3\n4\n5" | jq --raw-input '. | select (. != "") | {(.):123} | reduce . as $i ({}; . + $i)'
the reduction does nothing. Why? How to correct the reduction to produce single object having keys 1,2,3,4,5?
First, the initial .| is unnecessary.
Second, since your input is a stream, you will either need to use the -s option, or better, use the -n option with inputs.
So you could go with:
echo -e "1\n2\n\n\n3\n4\n5" |
jq -nR 'reduce (inputs|select(. != "")) as $i ({}; . + {($i): 123})'
though maybe {($i): null} might be more appropriate.
You were almost there. To convert from multiple results to a single object, you can run another jq in slurp mode:
echo -e "1\n2\n\n\n3\n4\n5" \
| jq --raw-input 'select (. != "") | {(.):123}' \
| jq --slurp 'reduce .[] as $o ({}; . + $o)'

tcsh passing a variable inside a shell script

I've defined a variable inside a shell script and I want to use it. For some reason, I cannot pass it into to command line that I need it in.
Here's my script which fails at the last lines
#! /usr//bin/tcsh -f
if ( $# != 2 ) then
echo "Usage: jump_sorter.sh <jump> <field to sort on>"
exit;
endif
set a = `cat $1 | tail -1` #prepares last row for check with loop
set b = $2 #this is the value last row will be checked for
set counter = 0
foreach i ($a)
if ($i == "$b") then
set bingo = $counter
echo "$bingo is the field to print from $a"
endif
set counter = `expr $counter + 1`
end
echo $bingo #this prints the correct value for using in the command below
cat $1 | awk '{print($bingo)}' | sort | uniq -c | sort -nr #but this doesn't work.
#when I use $9 instead of $bingo, it does work.
How can I pass $bingo into the final line correctly, please?
Update: following the accepted answer from Martin Tournoij, the correct way to handle the "$" sign in the command is:
cat $1 | awk "{print("\$"$bingo)}" | sort | uniq -c | sort -nr
The reason it doesn't work is because variables are only substituted inside double quotes ("), not single quotes ('), and you're using single quotes:
cat $1 | awk '{print($bingo)}' | sort | uniq -c | sort -nr
The following should work:
cat $1 | awk "{print($bingo)}" | sort | uniq -c | sort -nr
You also have an error here:
#! /usr//bin/tcsh -f
That should be:
#!/usr/bin/tcsh -f
Note that csh isn't usually recommended for scripting; it has many quirks and lacks some features like functions. Unless you really need to use csh, it's recommended to use a Bourne shell (/bin/sh, bash, zsh) or a scripting language (Python, Ruby, etc.) instead.

Find word count using wc and assign to a variable

i want the word count wc -w value be assigned to a variable
i've tried something like this, but i'm getting error, what is wrong?
winget="this is the first line"
wdCount=$winget | wc -w
echo $wdCount
You need to $(...) to assign the result:
wdCount=$(echo $winget | wc -w)
Or you could also avoid echo by using here-document:
wdCount=$(wc -w <<<$winget)
You can pass word count without the filename using the following:
num_of_lines=$(< "$file" wc -w)
See https://unix.stackexchange.com/a/126999/320461
You can use this to store the word count in variable:
word_count=$(wc -w filename.txt | awk -F ' ' '{print $1}'

How do I Get the distinct List of Special Characters from a File using GREP or SED?

I have a file which contains about 30000 Records delimited by '|'. I need to get a distinct list of special characters only from the file.
For Eg:
123|fasdf|%df&|pap,came|!
234|%^&asdf|34|'":|
My output should be:
|%&,!^'":
Any help would be greatly appreciated.
Thanks,
Velraj.
grep -o '[|%&,!^":]' input | sort -u
You have to list all your special characters inside brackets.
This will return each unique special character on its own line. If you really need a string with these characters you have to remove newlines afterwards, e.g.:
grep -o '[|%&,!^":]' input | sort -u | tr -d '\n'
UPDATE:
If you need to remove all characters which are not from 'a-zA-Z0-9' set then you can use this one:
grep -o '[^a-zA-Z0-9]' input | sort -u | tr -d '\n'
echo "123|fasdf|%df&|pap,came|! 234|%^&asdf|34|'\":|" \
| { tr -d '[[:alnum:]]'; printf "\n"; } \
| sed 's/\(.\)/\1_/g' \
| awk -v 'RS=_' '{print $0}' \
| sort -u \
| awk '{printf $0}END{printf "\n"}'
output
!"%&',:^||
You can replace the first line echo .... with cat fileName

Parsing each field and process it using 'awk'/'gawk'

Here is a query:
grep bar 'foo.txt' | awk '{print $3}'
The field name emitted by the 'awk' query are mangled C++ symbol names. I want to pass each to dem and finally output the output of 'dem'- i.e the demangled symbols.
Assume that the field separator is a ' ' (space).
awk is a pattern matching language. The grep is totally unnecessary.
awk '/bar/{print $3}' foot.txt
does what your example does.
Edit Fixed up a bit after reading the comments on the precedeing answer (I don't know a thing about dem...):
You can make use of the system call in awk with something like:
awk '/bar/{cline="dem " $3; system(cline)}' foot.txt
but this would spawn an instance of dem for each symbol processed. Very inefficient.
So lets get more clever:
awk '/bar/{list = list " " $3;}END{cline="dem " list; system(cline)}' foot.txt
BTW-- Untested as I don't have dem or your input.
Another thought: if you're going to use the xargs formulation offered by other posters, cut might well be more efficient than awk. At that point, however, you would need grep again.
How about
grep bar 'foo.txt' | awk '{ print $3 }' | xargs dem | awk '{ print $3 }'
This will print the demangled symbols, complete with argument lists in the case of methods:
awk '/bar/ { print $3 }' foo.txt | xargs dem | sed -e 's:.* == ::'
This will print the demangled symbols, without argument lists in the case of methods:
awk '/bar/ { print $3 }' foo.txt | xargs dem | sed -e 's:.* == \([^(]*\).*:\1:'
Cheers,
V.

Resources