Extract all hardcoded strings to string resource - android-studio

I know there is Alt + Enter combination to extract single String to string resource. But I am wondering is there anything that I can extract all string of my project into string resource?
Also Android studio not making same String to string resource if I make one of them.
String s = "Hello World";
String s2 = "Hello World";
For example. I make "Hello World" to string resource still another remain Hardcoded in same file as well in the project too.
String s = getString(R.string.helloworld);
String s2 = "Hello World";
If anyone know something like that.

As your requirements and as I know there is no such feature in android studio you were really searching for, But here are some alternative ways that can help you.
Go to "Analyze > Run Inspection ..", and type "Hardcoded strings". Run that in your whole project, and you will get an inspection results panel that will show all the hardcoded text of projects. Then hit Alt + Enter and you'll get an option to automatically extract that Strings.
Another approach is to Find and Replace But It's not better because of time consumption. To simplify the approach you can have a look at here for flexibility.

For hardcoded strings in XML layout files:
Click on Analyze -> Run inspection by name -> enter Hardcoded strings -> select the whole project -> OK.
Here, you will get all the hardcoded strings from your xml layout files only that u can extract to strings.xml by:
Click on the hardcoded text -> Alt + Enter -> extract from resource -> enter your corresponding resource name for that string -> OK
For hardcoded strings in Java class code:
Click on Analyze -> Run inspection by name -> enter Hardcoded texts -> select the whole project -> OK.
Here, you will get all the hardcoded strings from your Java class files only that u can extract to strings.xml by:
Click on the hardcoded text -> Alt + Enter -> extract from resource -> enter your corresponding resource name for that string -> OK -> add getString for each string resource created in your java code.
Hence, Hardcoded strings -> Java class code whereas
Hardcoded texts -> Xml layout files in Android Studio.

In Android 3.2.1 you can go to Edit->Find->Find In Path... and then search for android:text=" . This will give you a list of all the hardcoded strings in xml files.
Search for Toast.makeText to find all the toast items from the java files.
Search for setText(" to search for text sets in java files and so forth.
You can do searches like this for items you would like to find throughout the project and replace.

I wrote the following script to extract all hardcoded strings from an activity.xml file and add them to strings.xml. (Bash/Linux):
Usage: extractAll.sh activity_main.xml strings.xml
Original files are backed up before changes are made.
#!/bin/bash
################################################################################
# Extract All Hardcoded Strings From an Activity XML File and Save New
# Versions of the activity.xml and strings.xml
################################################################################
#check the number of arguments supplied, print usage if not 2
if [ "$#" -ne 2 ]; then
echo "extract all hardcoded strings from activity.xml and update .xml files"
echo "original files are saved with .bak extension"
echo "usage: $0 activity.xml strings.xml"
exit
fi
#backup input files
#TODO: save these backups in another folder so they don't cause build error
cp $1 $1.bak
cp $2 $2.bak
#grep for hardcoded strings, for each one sed out special characters, change
#all to lower case, replace space characters with underscores, truncate string
#variable names to 30 characters. The result will be the name of the new string
#variable entered in strings.xml
grep -Po "(?<=android:text=\")[^\"]+(?=\")" $1 | while read -r HARDSTRING ; do
STRINGVARNAME=`echo $HARDSTRING | sed 's/\([\d0-\d31]\|[\d33-\d35]\|\$\|[\d37-\d47]\|[\d58-\d64]\|[\d91-\d96]\|[\d123-\d126]\)//g'|sed -e 's/\(.*\)/\L\1/'|sed 's/ /_/g'|head -c 30`
#substitute each hardcoded string with the string variable name
sed -i "s/$HARDSTRING/#string\/$STRINGVARNAME/" $1
#get the number of lines in strings.xml file
NUMLINES=`wc -l < $2`
#insert string definition at second-to-last line of strings.xml
let "NUMLINES++" #I had to increment mine to get the desired result
#add an entry to the strings.xml defining the newly extracted string
sed -i "$NUMLINES""i\\ <string name=\""$STRINGVARNAME"\">$HARDSTRING</string>\\" $2
done
Final note: wc -l returned one less than expected in my test case using a strings.xml file created by Android Studio (I suspect because the last line had no newline). This caused sed -i to insert the new line at the third-to-last position instead of the desired second-to-last. My fix was to increment the result of wc -l using let.
References:
What are invalid characters in XML
sed one-liner to convert all uppercase to lowercase?
How to process each output line in a loop?
How can I truncate a line of text longer than a given length?
Linux Shell Script - String Comparison with wildcards
How to insert a string into second to last line of a file
Check number of arguments passed to a Bash script
https://askubuntu.com/questions/385528/how-to-increment-a-variable-in-bash
https://docs.oracle.com/cd/E82085_01/150/funtional_artifacts_guide/or-fasg-standards.htm
https://tldp.org/LDP/abs/html/refcards.html#AEN22828

I believe the shortcut you are looking for is (on a Mac) Alt + Command + C

Related

Data hidden in jpg

I am currently looking for hidden data in a jpg file but I have no clue on how to operate.
There is a jpg file containing text in a format I have never seen before :
-ne \xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x60\x00\x60\x00\x00\xff\xdb\x00\x43\x00\x06\x04\x04\x05\x04\x04\x06\x05\x05\x05\x06\x06\x06\x07\x09\x0e\x09\x09\x08\x08\x09\x12\x0d\x0d\x0a\x0e\x15\x12\x16\x16\x15\x12\x14\x14\x17\x1a\x21\x1c\x17\x18\x1f\x19\x14\x14\x1d\x27\x1d\x1f\x22\x23\x25\x25\x25\x16\x1c\x29\x2c\x28\x24\x2b\x21\x24\x25\x24\xff\xdb\x00\x43\x01\x06\x06\x06\x09\x08\x09\x11\x09\x09\x11\x24\x18\x14\x18\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\x24\xff\xc0\x00\x11\x08\x01\x8e\x03\x4e\x03\x01\x22\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xff\xc4\x00\xb5\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01\x7d\x01\x02\x03\x00\x04\x11\x05\x12\x21\x31\x41\x06\x13\x51\x61\x07\x22\x71\x14\x32\x81\x91\xa1\x08\x23
-ne \x42\xb1\xc1\x15\x52\xd1\xf0\x24\x33\x62\x72\x82\x09\x0a\x16\x17\x18\x19\x1a\x25\x26\x27\x28\x29\x2a\x34\x35\x36\x37\x38\x39\x3a\x43\x44\x45\x46\x47\x48\x49\x4a\x53\x54\x55\x56\x57\x58\x59\x5a\x63\x64\x65\x66\x67\x68\x69\x6a\x73\x74\x75\x76\x77\x78\x79\x7a\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xc4\x00\x1f\x01\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xff\xc4\x00\xb5\x11\x00\x02\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04\x00\x01\x02\x77\x00\x01\x02\x03\x11\x04\x05\x21\x31\x06\x12\x41\x51\x07\x61\x71\x13\x22\x32\x81\x08\x14\x42\x91\xa1\xb1\xc1\x09\x23\x33\x52\xf0\x15\x62\x72\xd1\x0a\x16\x24\x34\xe1\x25\xf1\x17\x18\x19\x1a\x26\x27\x28\x29\x2a\x35\x36\x37\x38\x39\x3a\x43\x44\x45\x46\x47\x48\x49
This is just the beggining of the file as there is at least a hundred lines.
The file type given by the command file : file.jpg: ASCII text, with very long lines
I tried some of the common tools to identify any patterns or hidden data like exiftools, strings, xxd but I found nothing.
If you have any idea on what to do it would be very much appreciated.
If it's a challenge of CTF, there are some common way to find out flag.
First try to find flag in file metadata, like description of file field
you can also try tool: stegsolve.jar.
In more advance sence, stego info hidden with some math calulation, give this tool a try: zsteg
Perhaps I'm misunderstanding the problem here, but if your file actually starts with a backslash character followed by the characters x, f, f, \, x, d, 8 and so on, then what you're looking at is the binary content of a JPG file that has been converted into ASCII text.
If so, you need to convert this back into binary data. For example, in Linux or MacOS, you could do this by entering the following on the command line:
echo -ne '\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01...etc...' > img.jpg
echo -ne '\x42\xb1\xc1\x15\x52\xd1\xf0\x24\x33\x62\x72\x82...etc...' >> img.jpg
(Note: > sends the results to a new file, and >> appends to the end of the file)
Or alternatively in Python:
with open("img.jpg","wb") as f:
f.write(b'\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01...etc...')
f.write(b'\x42\xb1\xc1\x15\x52\xd1\xf0\x24\x33\x62\x72\x82...etc...')
# and so on for all the other lines
Either way, you should end up with a file called img.jpg containing the image you're after.

Concatenate multiple yaml files with seperator

I need to concat multiple k8s deployment yaml files into one deployment script, and in doing so create a specific separator --- between each file. I know the specific depth at which the files will live as well as the filename, however I don't know how many there will be at a given time, so I've used the find statement below to
recursively search for the yaml file
concat each
piped in the tail command as a seperator
find . -type f -name 'deployment.yml' -exec cat {} + | tail -n +1 * > finalDeployment.yml
However, this creates broken yaml syntax by inserting the ==> <== delimeter:
I could simply have another task run a find/replace using the above as prefix/suffix tokens, however I'd like something more succinct within the above statement.
Is it possible to pipe in a specific character/set of characters a delimeter within a cat command, or is there another method to accomplish this?
What you want to do is not guaranteed to work. For example, you have these two YAML files:
foo: bar
and:
%YAML 1.2
---
baz
As you can see, the second file contains a directive. It also shows that --- in YAML is not a separator, but a directives end marker. It is optional if you don't have any directives like in the first document. If you concatenate both documents in the way you want to do it, you will get a document with two --- and %YAML 1.2 will be interpreted as content because it occurs after a directives end marker.
So what you actually want to do is to mark the end of each document with ..., the document end marker. After that marker, the parser is reset to its initial state, which guarantees that the second document is parsed exactly as it would have been when it was in a separate file.
Also, no harm is done by adding ... to the last document since it does not start another document implicitly. So your command could look like this (I depend on your statement that you know the depth at which the files lie here and as example, expect a depth of 3 directories):
echo -n > finalDeplayment.yml
for f in */*/*/deployment.yml; do
cat $f >> finalDeployment.yml; echo "..." >> finalDeployment.yml
done

In CMake how do turn a multi line output of a command into a list?

I want to do do something like this
execute_process(
COMMAND bash -c "git --git-dir ${CMAKE_SOURCE_DIR}/.git ls-files"
OUTPUT_VARIABLE TRACKED_FILES)
add_custom_target(all_file_project SOURCES ${TRACKED_FILES})
And the command itself seems to work as expected but the generated variable "TRACKED_FILES" contains only one logical entry (one multi line string) rather than a list of files.
Can I somehow turn a string containing multiple lines separated by a newline ("\n") into a list in CMake?
One option (as the title of my question suggests) is to actively split the string manually rather than interpreting a variable as list in the first place:
string(REPLACE "\n" ";" ADDITIONAL_PROJECT_FILES_LIST ${ADDITIONAL_PROJECT_FILES})
This works for me but it would be very nice to have something more abstract and less platform specific (e.g. I don't know whether this works on all OSes including Windows)
Something like execute_process(COMMAND find -type f OUTPUT_LIST_VARIABLE MY_LIST)
Or at least set(MY_LIST FROM_MULTILINE MY_MULTILINE_STRING)

Linux/bash: Change key category codes within script

I have a very simple script that's essentially an alias for find -iname, so I can find the path to a file whose name I sort of remember , but whose location I've definitely forgotten. I'd type myscript *cri*unis*, for example, to quickly locate crime_and_punishment.txt.
But now I am getting rather lazy about pressing the shift key to enter the wildcard character, so I'd like to make , be the wildcard character only when parsing the input parameters to my script.
It's similar to if I were using TeX and had to type a long table and wanted to temporarily make , be the column delimiter: I would type \bgroup \catcode`\,=4 and then enter \egroup when finished with my table.
And come to think of it, how do I enter a back-tick within an inline code snippet on this site's markdown?! The markdown should let me temporarily use ; to delimit an inline code snippet.
Not really sure I understand the question but if you would like to replace all , characters in the input with * characters. Something like this should work:
#!/bin/bash
search=`echo "$1" | tr "," "*"`
find -iname "$search"

Rename multiple files with different extensions on linux

I have a bunch of files with different extensions and i would like to add a suffix at the end of all of their names:
Fe2-K-D4.rac
Fe2-K-D4.plo
Fe2-K-D4_iso.xy
...
to
Fe2-K-D4-4cc8.rac
Fe2-K-D4-4cc8.plo
Fe2-K-D4-4cc8_iso.xy
...
I read a few posts about changing the extension using the rename tool but i don't know how to change the name and keep the same extension (I'm a recent linus user).
Thanks for any help
Using Extract filename and extension in Bash, I would say:
for file in *
do
extension="${file##*.}"
filename="${file%.*}"
mv "$file" "${filename}-4cc8.${extension}"
done
This loops through all the files, gets its name and extension and then moves it (that is, renames it) to the given name with an extra -4cc8 value before the extension.
Using rename:
rename 's/[.]([^.]+)$/-4cc8.$1/' *
s/[.]([^.]+)$/-4cc8.$1/ is a perl expression of the form s/PATTERN/REPLACEMENT/
which tells rename to do a global substition.
[.]([^.]+)$ is a regex pattern with the following meaning:
[.] match a literal period
( followed by a group
[ containing a character class
^. composed of anything except a literal period
]+ match 1-or-more characters from the character class
) end group
$ match the end of the string.
The replacement pattern, -4cc8.$1, tells rename to replace the matched text with a literal -4cc8. followed by text in the first group matched, i.e. whatever followed the literal period.

Resources